package work.mediway.common.transport;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.annotation.JsonInclude;

import org.apache.ibatis.type.Alias;

import java.awt.Color;
import java.awt.Font;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpStatus;
import cn.hutool.json.JSONUtil;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import work.mediway.common.domain.constant.CoreConstant;
import work.mediway.common.domain.enums.CodeAndMsgEnum;
import work.mediway.common.exception.GlobalDataException;
import work.mediway.common.util.HttpContextUtil;

/**
 * 通用返回结果类
 *
 * @author zhongyj <1126834403@qq.com><br/>
 * @date 2019/11/1
 */
@Slf4j
@ToString
@NoArgsConstructor
@Alias("cdrmp_responsevo")
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ResponseVO<T> {

    public static final String NOT_FOUND_DATA = "未找到数据";
    public static final long MIN_DATA_SIZE = 1L;
    public static final long NULL_DATA_SIZE = 0L;

    @Setter
    @Getter
    private Integer code;

    @Setter
    @Getter
    private String msg;

    @Setter
    @Getter
    private Object data;

    @Setter
    @Getter
    private Map<String, Object> other;

    @Setter
    @Getter
    private Long draw;

    @Setter
    @Getter
    private Long pageSize;

    @Setter
    @Getter
    private Long pages;

    @Setter
    @Getter
    private Long total;


    /**
     * 成功但不带数据
     **/
    public static ResponseVO success() {
        ResponseVO result = new ResponseVO();
        result.setCode(CodeAndMsgEnum.SUCCESS.getCode());
        result.setMsg(CodeAndMsgEnum.SUCCESS.getMessage());
        return result;
    }

    /**
     * 成功带描述
     **/
    public static ResponseVO success(String message) {
        ResponseVO result = new ResponseVO();
        result.setCode(200);
        result.setMsg(message);
        return result;
    }

    /**
     * 成功带数据
     **/
    public static ResponseVO success(Object object) {
        ResponseVO result = new ResponseVO();
        if (ObjectUtil.isEmpty(object))
            result = ResponseVO.failed(CodeAndMsgEnum.DB_RESOURCE_NULL);
        result.setCode(CodeAndMsgEnum.SUCCESS.getCode());
        result.setMsg(CodeAndMsgEnum.SUCCESS.getMessage());
        result.setData(CollUtil.newArrayList(object));
        result.setDraw(ResponseVO.MIN_DATA_SIZE);
        result.setPageSize(ResponseVO.MIN_DATA_SIZE);
        result.setPages(ResponseVO.MIN_DATA_SIZE);
        result.setTotal(ResponseVO.MIN_DATA_SIZE);
        if (object instanceof List) {
            result.setTotal((long) ((List<?>) object).size());
            if (CollUtil.isEmpty((List<?>) object))
                result = ResponseVO.failed(CodeAndMsgEnum.DB_RESOURCE_NULL);
            result.setData(object);
        }
        if (object instanceof Page<?>) return result.success((Page<?>) object, result);
        return result;
    }

    private ResponseVO success(Page<?> page, ResponseVO result) {
        if (ObjectUtil.isEmpty(page))
            result = ResponseVO.failed(CodeAndMsgEnum.DB_RESOURCE_NULL);
        result.setCode(CodeAndMsgEnum.SUCCESS.getCode());
        result.setMsg(CodeAndMsgEnum.SUCCESS.getMessage());
        result.setData(page.getRecords());
        result.setDraw(page.getCurrent());
        result.setPageSize(page.getSize());
        result.setPages(page.getPages());
        result.setTotal(page.getTotal());

        if (CollUtil.isEmpty(page.getRecords()))
            result = ResponseVO.failed(CodeAndMsgEnum.DB_RESOURCE_NULL);
        return result;
    }


    /**
     * 操作失败
     *
     * @return ResponseDTO
     */
    public static ResponseVO failed() {
        ResponseVO result = new ResponseVO();
        result.setCode(CodeAndMsgEnum.SUCCESS.getCode());
        result.setMsg(CodeAndMsgEnum.FAIL.getMessage());
        result.setData(CollUtil.newArrayList());
        result.setDraw(ResponseVO.NULL_DATA_SIZE);
        result.setPageSize(ResponseVO.NULL_DATA_SIZE);
        result.setPages(ResponseVO.NULL_DATA_SIZE);
        result.setTotal(ResponseVO.NULL_DATA_SIZE);
        return result;
    }

    /**
     * 失败
     **/
    public static ResponseVO failed(Integer code, String msg) {
        ResponseVO result = new ResponseVO();
        result.setCode(code);
        result.setMsg(msg);
        result.setData(CollUtil.newArrayList());
        result.setDraw(ResponseVO.NULL_DATA_SIZE);
        result.setPageSize(ResponseVO.NULL_DATA_SIZE);
        result.setPages(ResponseVO.NULL_DATA_SIZE);
        result.setTotal(ResponseVO.NULL_DATA_SIZE);
        return result;
    }

    public static ResponseVO failed(String message) {
        ResponseVO result = new ResponseVO();
        result.setCode(CodeAndMsgEnum.FAIL.getCode());
        result.setMsg(message);
        result.setData(CollUtil.newArrayList());
        result.setDraw(ResponseVO.NULL_DATA_SIZE);
        result.setPageSize(ResponseVO.NULL_DATA_SIZE);
        result.setPages(ResponseVO.NULL_DATA_SIZE);
        result.setTotal(ResponseVO.NULL_DATA_SIZE);
        return result;
    }

    public static ResponseVO failed(CodeAndMsgEnum resultCodeEnum) {
        ResponseVO result = new ResponseVO();
        result.setCode(resultCodeEnum.getCode());
        result.setMsg(resultCodeEnum.getMessage());
        result.setData(CollUtil.newArrayList());
        result.setDraw(ResponseVO.NULL_DATA_SIZE);
        result.setPageSize(ResponseVO.NULL_DATA_SIZE);
        result.setPages(ResponseVO.NULL_DATA_SIZE);
        result.setTotal(ResponseVO.NULL_DATA_SIZE);
        return result;
    }

    /**
     * 设置响应
     *
     * @param response    HttpServletResponse
     * @param contentType content-type
     * @param status      http状态码
     * @param value       响应内容
     * @throws IOException IOException
     */
    public static void makeResponse(HttpServletResponse response, String contentType,
                                    int status, Object value) throws IOException {
        response.setContentType(contentType);
        response.setStatus(status);
        response.setCharacterEncoding("UTF-8");
        response.getOutputStream().write(JSONUtil.toJsonStr(value).getBytes(StandardCharsets.UTF_8));
    }

    /**
     * 返回流数据
     *
     * @param response    HttpServletResponse
     * @param contentType String
     * @param status      int
     * @param value       byte[]
     */
    public static void makeResponse(HttpServletResponse response, String contentType,
                                    int status, byte[] value) {
        response.setContentType(contentType + ";charset=UTF-8");
        response.setStatus(status);
        response.setCharacterEncoding("UTF-8");
        try {
            response.getOutputStream().write(value);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
            throw new GlobalDataException(e.getMessage());
        }
    }

    public static ResponseVO successWithOther(Object object, Map<String, Object> other) {
        ResponseVO result = new ResponseVO();
        result.setCode(CodeAndMsgEnum.SUCCESS.getCode());
        result.setMsg(CodeAndMsgEnum.SUCCESS.getMessage());
        result.setData(object);
        result.setOther(other);
        result.setDraw(ResponseVO.MIN_DATA_SIZE);
        result.setPageSize(ResponseVO.MIN_DATA_SIZE);
        result.setPages(ResponseVO.MIN_DATA_SIZE);
        result.setTotal(ResponseVO.MIN_DATA_SIZE);
        return result;
    }

    /**
     * 失败
     **/
    public static ResponseVO error(Integer code, String msg) {
        ResponseVO result = new ResponseVO();
        result.setCode(code);
        result.setMsg(msg);
        result.setDraw(ResponseVO.NULL_DATA_SIZE);
        result.setPageSize(ResponseVO.NULL_DATA_SIZE);
        result.setPages(ResponseVO.NULL_DATA_SIZE);
        result.setTotal(ResponseVO.NULL_DATA_SIZE);
        return result;
    }

    /**
     * 生成图片返回
     *
     * @param imageText 图片展示信息
     */
    public static void makeImageAndResponse(String imageText) {
        String tmpPngPath = CoreConstant.TMP_FILE_DIR + UUID.fastUUID() + ".png";
        ImgUtil.createImage(imageText, new Font("宋体", Font.PLAIN, 18), Color.WHITE, Color.BLACK, ImgUtil.getImageOutputStream(FileUtil.newFile(tmpPngPath)));
        makeResponse(HttpContextUtil.getResponse(), FileUtil.getMimeType(tmpPngPath), HttpStatus.HTTP_OK, FileUtil.readBytes(tmpPngPath));
        FileUtil.del(tmpPngPath);
    }

    /**
     * 返回文件流
     *
     * @param filePath 文件路径
     */
    public static void makeResponse(String filePath) {
        if (FileUtil.isFile(filePath)) {
            makeResponse(HttpContextUtil.getResponse(), FileUtil.getMimeType(filePath), HttpStatus.HTTP_OK, FileUtil.readBytes(filePath));
            FileUtil.del(filePath);
        } else {
            makeImageAndResponse(StrUtil.format("【{}】不是一个文件", filePath));
        }
    }

}














